﻿(function($) {
    $.easyValidate = function() {
        var arg = arguments;
        if (typeof arg[0] == "string") {
            switch (arg[0]) {
                case "check":
                    var summaryErrorMessage = [], targets = [], groups = [];
                    var occureError = false;
                    var group = arg[1];
                    var summary = $.easyValidate.options.summary;

                    $($.easyValidate.options.targets).each(function() {
                        var target = $(this);
                        var opt = $(this).data('opts');

                        if (opt.enabled && (group == undefined || opt.group == group)) {
                            $.each(opt.validateOpts, function() {
                                var errText = __check(target, this);
                                //如果之前已经发生过错误，那么这个值永远都是true（已经发生过错误），否则检查这次是否有错误。
                                occureError = !occureError ? errText.length != 0 : true;
                                if (errText.length != 0 && !summary) {
                                    $.easyValidate.options.onError.call(target, errText, opt.group);
                                    return false;
                                }
                                else {
                                    if (errText.length != 0 && !summary) {
                                        summaryErrorMessage.push(errText.join(","));
                                        targets.push(target);
                                        groups.push(opt.group);
                                    }
                                }
                            });
                        }
                        if (occureError && !summary)
                            return false;
                    });

                    if (summaryErrorMessage.length != 0) {

                        $.easyValidate.options.onError.call($(targets), summaryErrorMessage, groups);
                    }
                    return !occureError;
                default:
                    _enable(arg[0] == "enable", arg[1]);
            }
        }
        else if (typeof arg[0] == "object") {
            $.extend($.easyValidate.options, arg[0]);
        }
    };

    $.easyValidate.options = {
        onError: function(message) { var me = message.join("\r\n"); alert(me); },
        onCorrect: false,
        focus: true,
        summary: false,
        targets: []
    };

    _enable = function(isEnable, group) {
        $.each($.easyValidate.options.targets, function() {
            var opt = $(this).data("opts");
            if (group == undefined || group == opt.group) {
                opt.enabled = isEnable;
            }
        });
    };

    _ini = function(target, defaultOpts, op) {
        /*
        1) 把target压入一个数组，方便以后查找
        2) 生成target的options集合.结构如下target.data['opts']={
        enabled,
        group,
        summary,
        {checkEvent}:vRequire.opts,vlengRequest.opts
        }
                
        */

        if (target.length == 0) {
            return target;
        }
        // 1)
        var targets = $.easyValidate.options.targets;
        target.each(function() {
            if ($.inArray(this, targets) == -1) {
                targets.push(this);
            }
        });

        //2)
        var opts = $.extend({}, defaultOpts, op);
        var keyOfData = 'opts';
        var targetOpts = target.data(keyOfData);
        if (targetOpts == undefined) {
            targetOpts = {
                group: opts.group,
                enabled: opts.enabled,
                summary: opts.summary,
                validateOpts: {} //每个验证器的options
            };
            target.data(keyOfData, targetOpts);
        }

        if (targetOpts.validateOpts[opts.event] == undefined) {
            targetOpts.validateOpts[opts.event] = [];
        }
        targetOpts.validateOpts[opts.event.toString()].push(opts);
        if (opts.event !== false) {
            if (targetOpts.validateOpts[opts.event].length == 1) {

                target.bind(opts.event, function(e) {
                    var errorMessage = __check(target, targetOpts.validateOpts[opts.event], e);
                    if (errorMessage.length == 0) {
                        return __doCorrect(target, opts.event);
                    }
                    else {
                        return _showError(target, targetOpts.validateOpts[opts.event][0], opts.event, errorMessage);
                    }
                });
            }
        }
        return target;
    };


    __check = function(target, validatorOptions, e) {

        var message = [];
        var targetOpts = target.data('opts');

        if (!targetOpts.enabled) {
            return message;
        }

        $(validatorOptions).each(function() {
            if (target.val().length == 0 && this.empty !== true) {
                //如果值为空，并且设定为不检查空值，那么就跳过，不作检查
                return true;
            }
            if (!this.check.call(target, this, e)) {
                message.push(this.errorText);
                if (!targetOpts.summary) {
                    return false;
                }
            }
        });
        return message;
    };

    __doCorrect = function(target, eventName) {
        var firstOpts = target.data('opts').validateOpts[eventName][0];
        var onCorrectFunction = $.isFunction(firstOpts.onCorrect) ? firstopts.onCorrect : $.easyValidate.options.onCorrect;
        if ($.isFunction(onCorrectFunction))
            onCorrectFunction.call(target, firstOpts);
    };

    _showError = function(target, currentOpts, eventName, errorText) {
        var targetOpts = target.data('opts');
        var onErrorFunction = $.isFunction(currentOpts.onError)
                            ? currentOpts.onError
                            : targetOpts.validateOpts[eventName][0].onError;
        onErrorFunction = onErrorFunction == undefined
                            ? $.easyValidate.options.onError
                            : onErrorFunction;
        var a = errorText != undefined ? $.makeArray(errorText) : $.makeArray(currentOpts.errorText);

        return onErrorFunction.call(target, a, targetOpts.group);
    };

    $.fn.vCustom = function(op, customerFunction) {
        if (customerFunction != undefined) {
            op.check = customerFunction;
        }
        $._ini($(this), $.fn.vCustom.defaults, op);
    };

    $.fn.vCustom.defaults = {
        group: null,
        enabled: true,
        summary: false,
        errorText: "验证失败",
        event: "blur",
        empty: false,
        check: function() { alert("请填写customFunction"); }
    };

    $.fn.vRequire = function(op) {
        return _ini($(this), $.fn.vRequire.defaults, op);
    };

    $.fn.vRequire.defaults = $.extend({}, $.fn.vCustom.defaults, {
        errorText: "输入有效值",
        empty: true,
        trim: true,
        check: function(op) {
            var a = op.trim ? $.trim(this.val()) : this.val();
            return /\w+/.test(a);
        }
    });

    $.fn.vRang = function(op) {
        $(this).attr("maxlength", op.max.length);
        return _ini($(this), $.fn.vRang.defaults, op);
    };

    $.fn.vRang.defaults = $.extend({}, $.fn.vCustom.defaults, {
        errorText: "请输入范围要在{min}和{max}之间的值", //类型根据max的设定
        max: 999,
        min: 0,
        check: function(op) {
            var val = this.val();
            op.errorText = op.errorText.replace("{min}", op.min).replace("{max}", op.max);
            var type = typeof op.max;
            if (type == 'number') {
                var ival = parseInt(val);
                if (isNaN(ival)) {
                    return false;
                }
                return (ival <= op.max && ival >= op.min);
            }
            else {
                return (val <= op.max && val >= op.min);
            }
        }
    });

    $.fn.vLength = function(op) {
        $(this).attr("maxlength", op.max);
        return _ini($(this), $.fn.vLength.defaults, op);
    };

    $.fn.vLength.defaults = $.extend({}, $.fn.vCustom.defaults, {
        min: 0,
        max: 9999,
        errorText: "长度要做{min}和{max}之间",
        check: function(opts) {
            var length = this.val().length;
            var message = opts.errorText;
            if (message.indexOf("{min}") != -1 || message.indexOf("{max}") != -1) {
                opts.errorText = message.replace("{min}", opts.min).replace("{max}", opts.max);
            }
            return length <= opts.max && length >= opts.min;
        }
    });

    $.fn.vCompare = function(op) {
        return _ini($(this), $.fn.vCompare.defaults, op);
    };

    $.fn.vCompare.defaults = $.extend({}, $.fn.vCustom.defaults,
     {
         target: false,
         errorText: "不匹配",
         operator: "==", //接受 <= >= < >等操作符
         check: function() {
             var a = arguments;
             var v = $.isFunction(a[0].target) ? a[0].target.call(this) : a[0].target.val();
             return eval("this.val()" + a[0].operator + "v");
         }
     });

    $.fn.vRegex = function(op) {
        return _ini($(this), $.fn.vRegex.defaults, op);
    };

    $.fn.vRegex.defaults = $.extend({}, $.fn.vCustom.defaults, {
        pattern: /.*/,
        errorText: "输入信息不正确",
        check: function(opts) {
            return opts.pattern.test(this.val());
        }
    });


    $.fn.vAjax = function(op) {
        return _ini($(this), $.fn.vAjax.defaults, op);
    };

    $.fn.vAjax.defaults = $.extend({}, $.fn.vCustom.defaults, {
        dataType: 'JSON',
        errorText: "输入信息不正确",
        onEndRequest: false, //请求成功后的，要做的处理
        onBeginRequest: false, //请求开始
        check: function(opts) {
            var data1 = opts.data();
            var result = $.ajax({
                url: opts.url,
                dataType: opts.dataType,
                data: data1
            });
            if ($.isFunction(opts.onEndRequest)) {
                return opts.onEndRequest(this, result);
            }
        }
    });

    //---------------一下是常用扩展--------------------
    $.fn.vNumber = function(op) {
        $(this).attr("maxlength", op.max.length);
        return _ini($(this), $.fn.vRang.defaults, op);
    };

    $.fn.vNumber.defaults = $.extend({}, $.fn.vRang.defaults, {
        errorText: "请输入范围在{min}和{max}之间的数字",
        check: function(opts) {
            var a = new RegExp("^\d{" + opts.min.toString().length + "," + opts.max.toString().length + "}$");
            opts.errorText = opts.errorText.replace("{min}", opts.min).replace("{max}", opts.max);
            var result = a.test(this.val());
            if (result) {
                var inte = parseFloat(this.val())
                return inte >= opts.min && inte <= opts.max;
            }
            return false;
        }
    });

    $.fn.vEmail = function(op) {
        return _ini($(this), $.fn.vRegex.defaults, { pattern: /^([A-Za-z0-9_\.-]+)@([\da-zA-Z\.-]+)\.([a-zA-Z\.]{2,6})$/ });
    }

})($);